package net.ibizsys.paas.dao;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;

import net.ibizsys.paas.core.DEDataSetFetchContext;
import net.ibizsys.paas.core.Errors;
import net.ibizsys.paas.core.IDEDBCallContext;
import net.ibizsys.paas.core.IDEDataQuery;
import net.ibizsys.paas.core.IDEDataQueryCode;
import net.ibizsys.paas.core.IDEDataQueryCodeCond;
import net.ibizsys.paas.core.IDEDataSet;
import net.ibizsys.paas.core.IDEDataSetCond;
import net.ibizsys.paas.core.IDEDataSetFetchContext;
import net.ibizsys.paas.core.IDEDataSetGroupParam;
import net.ibizsys.paas.core.IDEDataSetQuery;
import net.ibizsys.paas.core.IDEField;
import net.ibizsys.paas.core.IDataEntity;
import net.ibizsys.paas.core.IPostConstructable;
import net.ibizsys.paas.data.DataObject;
import net.ibizsys.paas.db.DBCallResult;
import net.ibizsys.paas.db.DBFetchResult;
import net.ibizsys.paas.db.IDBDialect;
import net.ibizsys.paas.db.IDataRow;
import net.ibizsys.paas.db.IDataSet;
import net.ibizsys.paas.db.IDataTable;
import net.ibizsys.paas.db.ISelectCond;
import net.ibizsys.paas.db.SqlParam;
import net.ibizsys.paas.db.SqlParamList;
import net.ibizsys.paas.demodel.IDEDBProcModel;
import net.ibizsys.paas.demodel.IDEDataSetModel;
import net.ibizsys.paas.demodel.IDataEntityModel;
import net.ibizsys.paas.demodel.ISqlCommandModel;
import net.ibizsys.paas.entity.IEntity;
import net.ibizsys.paas.entity.SimpleEntity;
import net.ibizsys.paas.exception.ErrorException;
import net.ibizsys.paas.service.SessionFactoryManager;
import net.ibizsys.paas.util.StringBuilderEx;
import net.ibizsys.paas.util.StringHelper;
import net.ibizsys.paas.web.IWebContext;
import net.ibizsys.paas.web.WebContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.jdbc.Work;

/**
 * 数据访问对象
 * 
 * @author lionlau
 * 
 */
public abstract class DAOBase <ET extends IEntity> implements IDAO<ET>,IPostConstructable
{
	private static final Log log = LogFactory.getLog(DAOBase.class);

	//private ThreadLocal<IWebContext> webContext = new ThreadLocal<IWebContext>();

	/**
	 * 获取数据SQL命令模型
	 */
	protected ISqlCommandModel getSqlCommandModel = null;
	
	
	/**
	 * 获取数据SQL命令模型
	 */
	protected ISqlCommandModel getTempSqlCommandModel = null;
	
	
	/**
	 * 检查主键SQL命令模型
	 */
	protected ISqlCommandModel checkKeySqlCommandModel = null;
	
	
	/**
	 * 检查主键SQL命令模型
	 */
	protected ISqlCommandModel checkKeyTempSqlCommandModel = null;
	
	
	
	/**
	 * 建立数据SQL命令模型 
	 */
	protected ISqlCommandModel createSqlCommandModel = null;
	
	
	/**
	 * 建立数据SQL命令模型 
	 */
	protected ISqlCommandModel createTempSqlCommandModel = null;
	
	
	/**
	 * 删除数据SQL命令模型
	 */
	protected ISqlCommandModel removeSqlCommandModel = null;
	
	
	/**
	 * 删除数据SQL命令模型
	 */
	protected ISqlCommandModel removeTempSqlCommandModel = null;
	
	
	private String strDSLink = null;
	
	
	private SessionFactory sessionFactory = null;
	
	private IDBDialect iDBDialect = null;
	
	protected class DBCallResultProxy
	{
		private DBCallResult dbCallResult = null;
		
		public DBCallResult getDBCallResult()
		{
			return this.dbCallResult;
		}
		
		public void setDBCallResult(DBCallResult dbCallResult)
		{
			this.dbCallResult = dbCallResult;
		}
	}
	
	public DAOBase()
	{
		//log.info(StringHelper.format("初始化DAO对象[%1$s]",this));
   }
	
	
	/**
	 * 获取DAO对象的标识
	 * @return
	 */
	protected String getDAOId()
	{
		return null;
	}
	
	
	/**
	 * 获取继承实体的数据访问对象
	 * @return
	 */
	protected IDAO getInheritDEDAO()
	{
		return null;
	}
	
		
	
	/**
	 * 获取上下文对象
	 * 
	 * @return
	 */
	@Override
	public IWebContext getWebContext()
	{
		return WebContext.getCurrent();
	}


	/**
	 * 支持数据库存储过程
	 * @param iDEDBCallContext
	 * @param strDEProcName
	 * @param entity
	 * @return
	 * @throws Exception
	 */
	public DBCallResult executeDEDBProc(IDEDBCallContext iDEDBCallContext, String strDEProcName,ET entity) throws Exception
	{
		Session session = this.getCurrentSession();
		
		log.debug(StringHelper.format("执行过程 %1$s", strDEProcName));

		final DBCallResult dbCallResult = new DBCallResult() ;
		
		final IDEDBProcModel iDEDBProcModel = (IDEDBProcModel)this.getDEModel().getDEAction(strDEProcName);
		
		final SqlParamList sqlParamList = new SqlParamList();
		
		this.fillDBProcSqlParams(iDEDBProcModel,entity,sqlParamList);
		
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult2 = null;
				try
				{
					dbCallResult2 = getRealDBDialect().callProc(connection,iDEDBProcModel.getDBProcName(),sqlParamList, iDEDBProcModel.getTimeOut());
					if(dbCallResult2.getRetCode()!=Errors.OK)
					{
						throw new Exception(dbCallResult2.getErrorInfo());
					}
					
					dbCallResult.from(dbCallResult2);
				}
				catch (Exception e)
				{
					if (dbCallResult2.getDataSet() != null)
					{
						dbCallResult2.getDataSet().close();
					}
					throw new SQLException(e.getMessage(),e);
				}
			}
		});

		return dbCallResult;
		
	}
	

	/**
	 * 填充过程参数
	 * @param iDEDBProcModel
	 * @param entity
	 * @param sqlParamList
	 * @throws Exception
	 */
	protected void fillDBProcSqlParams(IDEDBProcModel iDEDBProcModel,ET entity,SqlParamList sqlParamList)throws Exception
	{
		iDEDBProcModel.fillSqlParams(this.getDBType(), entity, this.getWebContext(), sqlParamList);
	}
	

	

	/**
	 * 获取数据集合结果
	 * @param iDEDataSetFetchContext
	 * @param strDEDataSetName
	 * @param bTempMode
	 * @return
	 * @throws Exception
	 */
	public DBFetchResult fetchDEDataSet(IDEDataSetFetchContext iDEDataSetFetchContext, String strDEDataSetName,boolean bTempMode) throws Exception
	{
		DEDataSetFetchContext.setCurrent(iDEDataSetFetchContext);
		
		ArrayList<IDEDataSetCond> userConditions = iDEDataSetFetchContext.getConditionList();
		IDEDataSet iDEDataSet =  this.getDEModel().getDEDataSet(strDEDataSetName);
		if(iDEDataSet instanceof IDEDataSetModel)
		{
			IDEDataSetModel iDEDataSetModel = (IDEDataSetModel) iDEDataSet;
			if(iDEDataSetModel.isCustomDS())
				return iDEDataSetModel.fetchDEDataSet(iDEDataSetFetchContext);
		}
		
		
		Session session = this.getCurrentSession();
		
		// 新建查询模型用户上下文
		StringBuilderEx script = new StringBuilderEx();
		StringBuilderEx declareScript = new StringBuilderEx();
		SqlParamList list = new SqlParamList();

		
		java.util.Iterator<IDEDataSetQuery> deDataSetQueries = iDEDataSet.getDEDataSetQueries();
		while(deDataSetQueries.hasNext())
		{
			IDEDataSetQuery iDEDataSetQuery = deDataSetQueries.next();
			IDEDataQueryCode iDEDataQueryCode = this.getDEModel().getDEDataQuery(iDEDataSetQuery.getDEDataQueryId()).getDEDataQueryCode(getRealDBDialect().getDBType());
			if (!StringHelper.isNullOrEmpty(iDEDataQueryCode.getDeclareCode()))
			{
				declareScript.append(iDEDataQueryCode.getDeclareCode());
				declareScript.append("\n");
				iDEDataQueryCode.fillDeclareParams(iDEDataSetFetchContext.getWebContext(), null, list);
			}
		}
		
		iDEDataSetFetchContext.fillDeclareParams(list);

		boolean bFirst = true;
		deDataSetQueries = iDEDataSet.getDEDataSetQueries();
		while(deDataSetQueries.hasNext())
		{
			IDEDataSetQuery iDEDataSetQuery = deDataSetQueries.next();
			IDEDataQueryCode iDEDataQueryCode = this.getDEModel().getDEDataQuery(iDEDataSetQuery.getDEDataQueryId()).getDEDataQueryCode(getRealDBDialect().getDBType());
			iDEDataQueryCode.fillQueryParams(iDEDataSetFetchContext.getWebContext(), null, list);
			
			if (bFirst)
				bFirst = false;
			else
			{
				script.append("UNION \n");
			}

			if(bTempMode)
			{
				script.append(iDEDataQueryCode.getQueryCodeTemp(iDEDataSetFetchContext, this.getRealDBDialect(), list));
			}
			else
				script.append(iDEDataQueryCode.getQueryCode(iDEDataSetFetchContext, this.getRealDBDialect(), list));
			
			if(!StringHelper.isNullOrEmpty(iDEDataSetFetchContext.getJoinScript()))
			{
				script.append(iDEDataQueryCode.getExtJoinSQL( iDEDataSetFetchContext, iDEDataSetFetchContext.getJoinScript(),this.getRealDBDialect(), list));
			}
			
			boolean bOutputWhere = false;
			boolean bCondFirst = true;
			
			java.util.Iterator<IDEDataQueryCodeCond> deDataQueryCodeConds = iDEDataQueryCode.getDEDataQueryCodeConds();
			while(deDataQueryCodeConds.hasNext())
			{
				IDEDataQueryCodeCond iDEDataQueryCodeCond = deDataQueryCodeConds.next();
				String strCondition =  iDEDataQueryCode.getConditionSQL( iDEDataSetFetchContext, iDEDataQueryCodeCond,this.getRealDBDialect(), list);
				if (StringHelper.isNullOrEmpty(strCondition))
					continue;

				if(!bOutputWhere)
				{
					script.append(" WHERE ");
					bOutputWhere = true;
				}
				
				if (bCondFirst)
					bCondFirst = false;
				else
					script.append(" AND ");

				script.append("(%1$s)",strCondition);
			}
			
			if (userConditions.size() != 0)
			{
				if(!bOutputWhere)
				{
					script.append(" WHERE ");
					bOutputWhere = true;
				}
				
				for (IDEDataSetCond iDEDataSetCond : userConditions)
				{
					if (!StringHelper.isNullOrEmpty(iDEDataSetCond.getDEDataQueryName()))
					{
						if (StringHelper.compare(iDEDataQueryCode.getName(), iDEDataSetCond.getDEDataQueryName(), false) != 0)
							continue;
					}

					
					String strCondition =  iDEDataQueryCode.getConditionSQL( iDEDataSetFetchContext, iDEDataSetCond,this.getRealDBDialect(), list);
					if (StringHelper.isNullOrEmpty(strCondition))
						continue;

					if (bCondFirst)
						bCondFirst = false;
					else
						script.append(" AND ");

					script.append("(%1$s)",strCondition);

				}
			}
		}
		
		if(iDEDataSet.isEnableGroup())
		{
			String strGroupSQL = declareScript.toString() + iDEDataSetFetchContext.getDeclareScript() + this.getGroupSQL(script.toString(),iDEDataSet);
			DBFetchResult dbFetchResult = fetchDataSet( session,null, strGroupSQL, iDEDataSetFetchContext.getStartRow(), iDEDataSetFetchContext.getPageSize(), list);
			if(dbFetchResult.isOk()&&dbFetchResult.getDataSet()!=null&&iDEDataSetFetchContext.isCacheDataSet())
			{
				dbFetchResult.getDataSet().cacheDataRow();
			}
			return dbFetchResult;
		}
		else
		{
			String strCountSQL = declareScript.toString() + iDEDataSetFetchContext.getDeclareScript() + getRealDBDialect().getCountSQL(script.toString());
			// 继续排序信息
			String strPagingSQL = 	this.getRealDBDialect().getPagingSQL(script.toString(), iDEDataSetFetchContext.getStartRow(), iDEDataSetFetchContext.getPageSize(), iDEDataSetFetchContext.getSort(),
					iDEDataSetFetchContext.getSortDir(), iDEDataSetFetchContext.getSort2(), iDEDataSetFetchContext.getSort2Dir());
		
			DBFetchResult dbFetchResult = fetchDataSet( session,strCountSQL, strPagingSQL, iDEDataSetFetchContext.getStartRow(), iDEDataSetFetchContext.getPageSize(), list);
			if(dbFetchResult.isOk()&&dbFetchResult.getDataSet()!=null&&iDEDataSetFetchContext.isCacheDataSet())
			{
				dbFetchResult.getDataSet().cacheDataRow();
			}
			return dbFetchResult;
		}

	}

	

	/**
	 * 获取数据查询结果
	 * @param iDEDataSetFetchContext
	 * @param strDEDataQueryName
	 * @param bTempMode
	 * @return
	 * @throws Exception
	 */
	public DBFetchResult fetchDEDataQuery(IDEDataSetFetchContext iDEDataSetFetchContext, String strDEDataQueryName,boolean bTempMode) throws Exception
	{
		DEDataSetFetchContext.setCurrent(iDEDataSetFetchContext);
		
		ArrayList<IDEDataSetCond> userConditions = iDEDataSetFetchContext.getConditionList();
		IDEDataQuery iDEDataQuery =  this.getDEModel().getDEDataQuery(strDEDataQueryName);
		
		
		Session session = this.getCurrentSession();
		
		// 新建查询模型用户上下文
		StringBuilderEx script = new StringBuilderEx();
		StringBuilderEx declareScript = new StringBuilderEx();
		SqlParamList list = new SqlParamList();

		IDEDataQueryCode iDEDataQueryCode = this.getDEModel().getDEDataQuery(iDEDataQuery.getId()).getDEDataQueryCode(getRealDBDialect().getDBType());
		if (!StringHelper.isNullOrEmpty(iDEDataQueryCode.getDeclareCode()))
		{
			declareScript.append(iDEDataQueryCode.getDeclareCode());
			declareScript.append("\n");
			iDEDataQueryCode.fillDeclareParams(iDEDataSetFetchContext.getWebContext(), null, list);
		}
		
		iDEDataSetFetchContext.fillDeclareParams(list);
		iDEDataQueryCode.fillQueryParams(iDEDataSetFetchContext.getWebContext(), null, list);
		
		if(bTempMode)
		{
			script.append(iDEDataQueryCode.getQueryCodeTemp());
		}
		else
			script.append(iDEDataQueryCode.getQueryCode());
		
		if(!StringHelper.isNullOrEmpty(iDEDataSetFetchContext.getJoinScript()))
		{
			script.append(iDEDataQueryCode.getExtJoinSQL( iDEDataSetFetchContext, iDEDataSetFetchContext.getJoinScript(),this.getRealDBDialect(), list));
		}
		
		boolean bOutputWhere = false;
		boolean bCondFirst = true;
		
		java.util.Iterator<IDEDataQueryCodeCond> deDataQueryCodeConds = iDEDataQueryCode.getDEDataQueryCodeConds();
		while(deDataQueryCodeConds.hasNext())
		{
			IDEDataQueryCodeCond iDEDataQueryCodeCond = deDataQueryCodeConds.next();
			String strCondition =  iDEDataQueryCode.getConditionSQL( iDEDataSetFetchContext, iDEDataQueryCodeCond,this.getRealDBDialect(), list);
			if (StringHelper.isNullOrEmpty(strCondition))
				continue;
			
			if(!bOutputWhere)
			{
				script.append(" WHERE ");
				bOutputWhere = true;
			}

			if (bCondFirst)
				bCondFirst = false;
			else
				script.append(" AND ");

			script.append("(%1$s)",strCondition);
		}
		
		if (userConditions.size() != 0)
		{
			if(!bOutputWhere)
			{
				script.append(" WHERE ");
				bOutputWhere = true;
			}
			
			for (IDEDataSetCond iDEDataSetCond : userConditions)
			{
				if (!StringHelper.isNullOrEmpty(iDEDataSetCond.getDEDataQueryName()))
				{
					if (StringHelper.compare(iDEDataQueryCode.getName(), iDEDataSetCond.getDEDataQueryName(), false) != 0)
						continue;
				}

				
				String strCondition =  iDEDataQueryCode.getConditionSQL( iDEDataSetFetchContext, iDEDataSetCond,this.getRealDBDialect(), list);
				if (StringHelper.isNullOrEmpty(strCondition))
					continue;

				if (bCondFirst)
					bCondFirst = false;
				else
					script.append(" AND ");

				script.append("(%1$s)",strCondition);

			}
		}
		
		String strCountSQL = "";
		if(iDEDataSetFetchContext.isFetchTotalRow())
		{
			strCountSQL = declareScript.toString() + iDEDataSetFetchContext.getDeclareScript() + getRealDBDialect().getCountSQL(script.toString());
		}
		
		String strPagingSQL = "";
		if(iDEDataSetFetchContext.isFetchData())
		{
			if(StringHelper.isNullOrEmpty(iDEDataSetFetchContext.getSort()) && StringHelper.isNullOrEmpty(iDEDataSetFetchContext.getSort2())
					&& (iDEDataSetFetchContext.getStartRow()==0) && (iDEDataSetFetchContext.getPageSize()==1))
					strPagingSQL =  script.toString();
			else
			{
				strPagingSQL = this.getRealDBDialect().getPagingSQL(script.toString(), iDEDataSetFetchContext.getStartRow(), iDEDataSetFetchContext.getPageSize(), iDEDataSetFetchContext.getSort(),
						iDEDataSetFetchContext.getSortDir(), iDEDataSetFetchContext.getSort2(), iDEDataSetFetchContext.getSort2Dir());
			}
				
		}
		
		DBFetchResult dbFetchResult = fetchDataSet( session,strCountSQL, strPagingSQL, iDEDataSetFetchContext.getStartRow(), iDEDataSetFetchContext.getPageSize(), list);
		if(dbFetchResult.isOk()&&dbFetchResult.getDataSet()!=null&&iDEDataSetFetchContext.isCacheDataSet())
		{
			dbFetchResult.getDataSet().cacheDataRow();
		}
		return dbFetchResult;

	}
	
	/**
	 * 获取数据集合结果
	 * @param session
	 * @param strCountSQL
	 * @param strPagingSQL
	 * @param nStartPos
	 * @param nPageSize
	 * @param list
	 * @return
	 * @throws Exception
	 */
	protected DBFetchResult fetchDataSet(Session session,String strCountSQL, String strPagingSQL, int nStartPos, int nPageSize, SqlParamList list) throws Exception
	{
		final DBFetchResult dbFetchResult = new DBFetchResult();
		final String strCountSQL2 = strCountSQL;
		final String strPagingSQL2 = strPagingSQL;
		final int nStartPos2 = nStartPos;
		final int nPageSize2 = nPageSize;
		final SqlParamList list2 = list;
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			
			if(!StringHelper.isNullOrEmpty(strPagingSQL))
			{
				sb.append("查询SQL\r\n%1$s", strPagingSQL);
				int nIndex =0;
				for(SqlParam sqlParam:  list)
				{
					sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
					nIndex++;
				}
				sb.append("\r\n");
			}
			
			if(!StringHelper.isNullOrEmpty(strCountSQL))
			{
				sb.append("分页SQL\r\n%1$s", strCountSQL);
				int nIndex =0;
				for(SqlParam sqlParam:  list)
				{
					sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
					nIndex++;
				}	
			}
			
			log.debug(sb.toString());
		}
		

		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				try
				{
					if(!StringHelper.isNullOrEmpty(strPagingSQL2))
					{
						DBCallResult dbCallResult = getRealDBDialect().callSql(connection, strPagingSQL2, list2, -1);
						if (dbCallResult.isOk())
						{
							IDataSet iDataSet = dbCallResult.getDataSet();
							dbFetchResult.setDataSet(iDataSet);
						}
						else
						{
							throw new Exception(dbCallResult.getErrorInfo());
						}
					}
					

					if(!StringHelper.isNullOrEmpty(strCountSQL2))
					{
						DBCallResult dbCallResult = getRealDBDialect().callSql(connection, strCountSQL2, list2, -1);
						if (dbCallResult.isOk())
						{
							IDataSet iDataSet = dbCallResult.getDataSet();
							if (iDataSet != null)
							{
								IDataRow iDataRow = iDataSet.getDataTable(0).next();
								dbFetchResult.setTotalRow(Integer.parseInt(iDataRow.get("TOTALROW").toString()));
								iDataSet.close();
							}
						}
						else
						{
							throw new Exception(dbCallResult.getErrorInfo());
						}
					}
				}
				catch (Exception e)
				{
					if (dbFetchResult.getDataSet() != null)
					{
						dbFetchResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbFetchResult;

	}



	/**
	 * 获取实体模型对象
	 * @return
	 */
	public abstract IDataEntityModel getDEModel();
	
	
	
	
	
	/**
	 * 获取当前数据库类型
	 * @return
	 */

	protected String getDBType(){return this.getRealDBDialect().getDBType();}
	
	
	
	
	/**
	 * GET 操作
	 * @param iDEDBCallContext
	 * @param et
	 * @param bTempMode
	 * @return
	 * @throws Exception
	 */
	@Override
	public DBCallResult executeGetSql( IDEDBCallContext iDEDBCallContext, ET et,boolean bTempMode) throws Exception
	{
		Session session = this.getCurrentSession();
		
		if(bTempMode)
		{
			if(getTempSqlCommandModel==null)
				getTempSqlCommandModel = this.getDEModel().getGetSqlCommandModel(this.getRealDBDialect(),bTempMode);
		}
		else
		{
			if(getSqlCommandModel==null)
				getSqlCommandModel = this.getDEModel().getGetSqlCommandModel(this.getRealDBDialect(),bTempMode);
		}
	
		
		
		
		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();
		final ISqlCommandModel iSqlCommandModel = bTempMode?getTempSqlCommandModel:getSqlCommandModel;

		
		SqlParamList sqlParamList = new SqlParamList();
		iSqlCommandModel.fillSqlParams(et, this.getWebContext(), sqlParamList);
		
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sBuilderEx = new StringBuilderEx();
			sBuilderEx.append("查询SQL\r\n%1$s",iSqlCommandModel.getSql());
			int nIndex =0;
			for(SqlParam sqlParam:  sqlParamList)
			{
				sBuilderEx.append(StringHelper.format("\r\n[%1$s]%2$s==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue()));
				nIndex++;
			}
			log.debug(sBuilderEx.toString());
					
		}
		
		
		final SqlParamList sqlParamList2 = sqlParamList;

		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult = null;
				try
				{
					dbCallResult = getRealDBDialect().callSql(connection, iSqlCommandModel.getSql(), sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}
	
	@Override
	public DBCallResult executeCheckKeySql( IDEDBCallContext iDEDBCallContext, ET et,boolean bTempMode) throws Exception
	{
		Session session = this.getCurrentSession();
		
		if(bTempMode)
		{
			if(checkKeyTempSqlCommandModel==null)
				checkKeyTempSqlCommandModel = this.getDEModel().getCheckKeySqlCommandModel(this.getRealDBDialect(),bTempMode);
		}
		else
		{
			if(checkKeySqlCommandModel==null)
				checkKeySqlCommandModel = this.getDEModel().getCheckKeySqlCommandModel(this.getRealDBDialect(),bTempMode);
		}
	
		
		
		final ISqlCommandModel iSqlCommandModel = bTempMode?checkKeyTempSqlCommandModel:checkKeySqlCommandModel;

		
		SqlParamList sqlParamList = new SqlParamList();
		iSqlCommandModel.fillSqlParams(et, this.getWebContext(), sqlParamList);
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sBuilderEx = new StringBuilderEx();
			sBuilderEx.append("查询SQL\r\n%1$s",iSqlCommandModel.getSql());
			int nIndex =0;
			for(SqlParam sqlParam:  sqlParamList)
			{
				sBuilderEx.append(StringHelper.format("\r\n[%1$s]%2$s==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue()));
				nIndex++;
			}
			log.debug(sBuilderEx.toString());
		}
		
		
		final SqlParamList sqlParamList2 = sqlParamList;
		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();

		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult = null;
				try
				{
					dbCallResult = getRealDBDialect().callSql(connection, iSqlCommandModel.getSql(), sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}
	
	
	
	
	/**
	 * Create 操作
	 * @param iDEDBCallContext
	 * @param et
	 * @param bTempMode
	 * @return
	 * @throws Exception
	 */
	@Override
	public DBCallResult executeCreateSql(IDEDBCallContext iDEDBCallContext, ET et,boolean bTempMode) throws Exception
	{
		Session session = this.getCurrentSession();
		
		if(bTempMode)
		{
			if(createTempSqlCommandModel==null)
				createTempSqlCommandModel = this.getDEModel().getCreateSqlCommandModel(this.getRealDBDialect(),bTempMode);
		}
		else
		{
			if(createSqlCommandModel==null)
				createSqlCommandModel = this.getDEModel().getCreateSqlCommandModel(this.getRealDBDialect(),bTempMode);
		}
		
		
		if(getInheritDEDAO()!=null)
		{
			fillInheritEntity(et);
		}
		

		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();
		final ISqlCommandModel iSqlCommandModel = ( bTempMode?createTempSqlCommandModel:createSqlCommandModel);

		
		SqlParamList sqlParamList = new SqlParamList();
		iSqlCommandModel.fillSqlParams(et, this.getWebContext(), sqlParamList);
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("插入SQL\r\n%1$s",( bTempMode?createTempSqlCommandModel:createSqlCommandModel).getSql());
			int nIndex =0;
			for(SqlParam sqlParam:  sqlParamList)
			{
				sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
				nIndex++;
			}
			log.debug(sb.toString());
		}
		
		final SqlParamList sqlParamList2 = sqlParamList;
		final IDEDBCallContext iDEDBCallContext2 = iDEDBCallContext;
		final ET et2 = et;
		final boolean bTempMode2 = bTempMode;
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult = null;
				try
				{
					if(getInheritDEDAO()!=null)
					{
						DBCallResult dbCallResult2 = getInheritDEDAO().executeCreateSql(iDEDBCallContext2, et2,bTempMode2);
						if (!dbCallResult2.isOk())
						{
							throw new Exception(dbCallResult2.getErrorInfo());
						}
						if(dbCallResult2.getDataSet()!=null)
						{
							dbCallResult2.getDataSet().cacheDataRow();
						}
					}
					
					dbCallResult = getRealDBDialect().callSql(connection, iSqlCommandModel.getSql(), sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
						if(dbCallResult.getDataSet()!=null)
						{
							dbCallResult.getDataSet().cacheDataRow();
						}
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}

	/**
	 * Update 操作
	 * @param iDEDBCallContext
	 * @param et
	 * @param bTempMode
	 * @return
	 * @throws Exception
	 */
	@Override
	public DBCallResult executeUpdateSql( IDEDBCallContext iDEDBCallContext, ET et,boolean bTempMode) throws Exception
	{
		Session session = this.getCurrentSession();
		
		ISqlCommandModel	updateSqlCommandModel = this.getDEModel().getUpdateSqlCommandModel(this.getRealDBDialect(),et,bTempMode);
		
		if(getInheritDEDAO()!=null)
		{
			fillInheritEntity(et);
		}
		
		
		

		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();
		final ISqlCommandModel iSqlCommandModel = updateSqlCommandModel;

		
		SqlParamList sqlParamList = new SqlParamList();
		iSqlCommandModel.fillSqlParams(et, this.getWebContext(), sqlParamList);
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("更新SQL\r\n%1$s", updateSqlCommandModel.getSql());
			int nIndex =0;
			for(SqlParam sqlParam:  sqlParamList)
			{
				sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
				nIndex++;
			}
			log.debug(sb.toString());
		}
		
		
		final SqlParamList sqlParamList2 = sqlParamList;
		final IDEDBCallContext iDEDBCallContext2 = iDEDBCallContext;
		final ET et2 = et;
		final boolean bTempMode2 = bTempMode;
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult = null;
				try
				{
					if(getInheritDEDAO()!=null)
					{
						DBCallResult dbCallResult2 = getInheritDEDAO().executeUpdateSql(iDEDBCallContext2, et2,bTempMode2);
						if (!dbCallResult2.isOk())
						{
							throw new Exception(dbCallResult2.getErrorInfo());
						}
						if(dbCallResult2.getDataSet()!=null)
						{
							dbCallResult2.getDataSet().cacheDataRow();
						}
					}
					
					dbCallResult = getRealDBDialect().callSql(connection, iSqlCommandModel.getSql(), sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
						if(dbCallResult.getDataSet()!=null)
						{
							dbCallResult.getDataSet().cacheDataRow();
						}
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}

	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.dao.IDAO#executeSysUpdateSql(net.ibizsys.paas.core.IDEDBCallContext, net.ibizsys.paas.entity.IEntity, boolean)
	 */
	@Override
	public DBCallResult executeSysUpdateSql( IDEDBCallContext iDEDBCallContext, ET et,boolean bTempMode) throws Exception
	{
		Session session = this.getCurrentSession();
		
		ISqlCommandModel	updateSqlCommandModel = this.getDEModel().getSysUpdateSqlCommandModel(this.getRealDBDialect(),et,bTempMode);
		
		if(getInheritDEDAO()!=null)
		{
			fillInheritEntity(et);
		}
		

		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();
		final ISqlCommandModel iSqlCommandModel = updateSqlCommandModel;

		
		SqlParamList sqlParamList = new SqlParamList();
		iSqlCommandModel.fillSqlParams(et, this.getWebContext(), sqlParamList);
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("更新SQL\r\n%1$s", updateSqlCommandModel.getSql());
			int nIndex =0;
			for(SqlParam sqlParam:  sqlParamList)
			{
				sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
				nIndex++;
			}
			log.debug(sb.toString());
		}
		
		
		final SqlParamList sqlParamList2 = sqlParamList;
		final IDEDBCallContext iDEDBCallContext2 = iDEDBCallContext;
		final ET et2 = et;
		final boolean bTempMode2 = bTempMode;
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult = null;
				try
				{
					if(getInheritDEDAO()!=null)
					{
						DBCallResult dbCallResult2 = getInheritDEDAO().executeSysUpdateSql(iDEDBCallContext2, et2,bTempMode2);
						if (!dbCallResult2.isOk())
						{
							throw new Exception(dbCallResult2.getErrorInfo());
						}
						if(dbCallResult2.getDataSet()!=null)
						{
							dbCallResult2.getDataSet().cacheDataRow();
						}
					}
					
					dbCallResult = getRealDBDialect().callSql(connection, iSqlCommandModel.getSql(), sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
						if(dbCallResult.getDataSet()!=null)
						{
							dbCallResult.getDataSet().cacheDataRow();
						}
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}
	
	/**
	 * Select 操作
	 * @param iDEDBCallContext
	 * @param iSelectCond
	 * @param bTempMode
	 * @return
	 * @throws Exception
	 */
	@Override
	public DBCallResult executeSelectSql(IDEDBCallContext iDEDBCallContext,ISelectCond iSelectCond,boolean bTempMode) throws Exception
	{
		Session session = this.getCurrentSession();
		
		ISqlCommandModel	selectSqlCommandModel = this.getDEModel().getSelectSqlCommandModel(this.getRealDBDialect(),iSelectCond,bTempMode);

		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();
		final ISqlCommandModel iSqlCommandModel = selectSqlCommandModel;

		
		SqlParamList sqlParamList = new SqlParamList();
		iSqlCommandModel.fillSqlParams(iSelectCond, this.getWebContext(), sqlParamList);
		
		final SqlParamList sqlParamList2 = sqlParamList;

		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("查询 SQL\r\n%1$s", selectSqlCommandModel.getSql());
			int nIndex =0;
			for(SqlParam sqlParam:  sqlParamList)
			{
				sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
				nIndex++;
			}
			log.debug(sb.toString());
		}
		
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult =  null;
				try
				{
					dbCallResult = getRealDBDialect().callSql(connection, iSqlCommandModel.getSql(), sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}
	
	
	/**
	 * Remove 操作
	 * @param iDEDBCallContext
	 * @param et
	 * @param bTempMode
	 * @return
	 * @throws Exception
	 */
	@Override
	public DBCallResult executeRemoveSql( IDEDBCallContext iDEDBCallContext, ET et,boolean bTempMode) throws Exception
	{
		Session session = this.getCurrentSession();
		
		if(bTempMode)
		{
			if(removeTempSqlCommandModel==null)
				removeTempSqlCommandModel = this.getDEModel().getRemoveSqlCommandModel(this.getRealDBDialect(),bTempMode);
		}
		else
		{
			if(removeSqlCommandModel==null)
				removeSqlCommandModel = this.getDEModel().getRemoveSqlCommandModel(this.getRealDBDialect(),bTempMode);
		}
		
		
		if(getInheritDEDAO()!=null)
		{
			fillInheritEntity(et);
		}
		
		
		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();
		final ISqlCommandModel iSqlCommandModel = (bTempMode?removeTempSqlCommandModel:removeSqlCommandModel);

		
		SqlParamList sqlParamList = new SqlParamList();
		iSqlCommandModel.fillSqlParams(et, this.getWebContext(), sqlParamList);
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("删除SQL\r\n%1$s", (bTempMode?removeTempSqlCommandModel:removeSqlCommandModel).getSql());
			int nIndex =0;
			for(SqlParam sqlParam:  sqlParamList)
			{
				sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
				nIndex++;
			}
			log.debug(sb.toString());
		}
		
		
		
		final SqlParamList sqlParamList2 = sqlParamList;
		final IDEDBCallContext iDEDBCallContext2 = iDEDBCallContext;
		final ET et2 = et;
		final boolean bTempMode2 = bTempMode;
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult = null;
				try
				{
					dbCallResult = getRealDBDialect().callSql(connection, iSqlCommandModel.getSql(), sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
					
					if(getInheritDEDAO()!=null)
					{
						dbCallResult = getInheritDEDAO().executeRemoveSql(iDEDBCallContext2, et2,bTempMode2);
						if (!dbCallResult.isOk())
						{
							throw new Exception(dbCallResult.getErrorInfo());
						}
					}
					
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}
	
	

	/**
	 * Remove 操作，通过查询条件
	 * @param iDEDBCallContext
	 * @param iSelectCond
	 * @param bTempMode
	 * @return
	 * @throws Exception
	 */
	@Override
	public DBCallResult executeRemoveSql(IDEDBCallContext iDEDBCallContext,ISelectCond iSelectCond,boolean bTempMode) throws Exception
	{
//		Session session = this.getCurrentSession();
//		
//		ISqlCommandModel	removeSqlCommandModel = this.getDEModel().getRemoveSqlCommandModel(this.getRealDBDialect(),iSelectCond,bTempMode);
//
//		final DBFetchResult dbFetchResult = new DBFetchResult();
//		final ISqlCommandModel iSqlCommandModel = removeSqlCommandModel;
//
//		
//		SqlParamList sqlParamList = new SqlParamList();
//		iSqlCommandModel.fillSqlParams(iSelectCond, this.getWebContext(), sqlParamList);
//		
//		final SqlParamList sqlParamList2 = sqlParamList;
//
//		if(log.isDebugEnabled())
//		{
//			StringBuilderEx sb = new StringBuilderEx();
//			sb.append("删除 SQL\r\n%1$s", removeSqlCommandModel.getSql());
//			int nIndex =0;
//			for(SqlParam sqlParam:  sqlParamList)
//			{
//				sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
//				nIndex++;
//			}
//			log.debug(sb.toString());
//		}
//		
//		session.doWork(new Work()
//		{
//			@Override
//			public void execute(Connection connection) throws SQLException
//			{
//				try
//				{
//					DBCallResult dbCallResult = getRealDBDialect().callSql(connection, iSqlCommandModel.getSql(), sqlParamList2, -1);
//					if (dbCallResult.isOk())
//					{
//						IDataSet iDataSet = dbCallResult.getDataSet();
//						dbFetchResult.setDataSet(iDataSet);
//					}
//					else
//					{
//						throw new Exception(dbCallResult.getErrorInfo());
//					}
//				}
//				catch (Exception e)
//				{
//					if (dbFetchResult.getDataSet() != null)
//					{
//						dbFetchResult.getDataSet().close();
//					}
//					throw new SQLException(e.getMessage(),e);
//				}
//			}
//		});
//
//		return dbFetchResult;
		
		throw new Exception("没有实现");
	}
	
	
	
	@Override
	public ArrayList<IEntity> executeRawSelectSql( IDEDBCallContext iDEDBCallContext, String strSql,SqlParamList sqlParamList) throws Exception
	{
		Session session = this.getCurrentSession();
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("SQL\r\n%1$s", strSql);
			int nIndex =0;
			if(sqlParamList!=null)
			{
				for(SqlParam sqlParam:  sqlParamList)
				{
					sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
					nIndex++;
				}
			}
			log.debug(sb.toString());
		}
		
		final String strSql2 =strSql;
		final DBFetchResult dbFetchResult = new DBFetchResult();
		final SqlParamList sqlParamList2 = sqlParamList;
		final ArrayList<IEntity> entityList = new  ArrayList<IEntity>();
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				try
				{
					DBCallResult dbCallResult = getRealDBDialect().callSql(connection, strSql2, sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						IDataSet iDataSet = dbCallResult.getDataSet();
						if (iDataSet == null || (iDataSet.getDataTableCount() == 0))
							throw new ErrorException(Errors.INVALIDDATA);
						
						IDataTable iDataTable = iDataSet.getDataTable(0);
						iDataTable.cacheRows(-1);
						int nCount = iDataTable.getCachedRowCount();
						for(int i=0;i<nCount;i++)
				        {
				            IDataRow iDataRow = iDataTable.getCachedRow(i);
				            SimpleEntity simpleEntity = new SimpleEntity ();
				            DataObject.fromDataRow(simpleEntity, iDataRow,false);
				            entityList.add(simpleEntity);
				        }
						
						iDataSet.close();
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
					
				}
				catch (Exception e)
				{
					if (dbFetchResult.getDataSet() != null)
					{
						dbFetchResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return entityList;
	}
	
	
	@Override
	public IEntity executeRawSelectOneSql( IDEDBCallContext iDEDBCallContext, String strSql,SqlParamList sqlParamList) throws Exception
	{
		Session session = this.getCurrentSession();
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("SQL\r\n%1$s", strSql);
			int nIndex =0;
			if(sqlParamList!=null)
			{
				for(SqlParam sqlParam:  sqlParamList)
				{
					sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
					nIndex++;
				}
			}
			log.debug(sb.toString());
		}
		
		final String strSql2 =strSql;
		final DBFetchResult dbFetchResult = new DBFetchResult();
		final SqlParamList sqlParamList2 = sqlParamList;
		final ArrayList<IEntity> entityList = new  ArrayList<IEntity>();
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				try
				{
					DBCallResult dbCallResult = getRealDBDialect().callSql(connection, strSql2, sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						IDataSet iDataSet = dbCallResult.getDataSet();
						if (iDataSet == null || (iDataSet.getDataTableCount() == 0))
							throw new ErrorException(Errors.INVALIDDATA);
						
						IDataTable iDataTable = iDataSet.getDataTable(0);
						iDataTable.cacheRows(1);
						int nCount = iDataTable.getCachedRowCount();
						for(int i=0;i<nCount;i++)
				        {
				            IDataRow iDataRow = iDataTable.getCachedRow(i);
				            SimpleEntity simpleEntity = new SimpleEntity ();
				            DataObject.fromDataRow(simpleEntity, iDataRow,false);
				            entityList.add(simpleEntity);
				        }
						
						iDataSet.close();
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
					
				}
				catch (Exception e)
				{
					if (dbFetchResult.getDataSet() != null)
					{
						dbFetchResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		if(entityList.size()==0)
		{
			return null;
			//throw new ErrorException(Errors.INVALIDDATA);
		}
		return entityList.get(0);
	}
	
	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.dao.IDAO#executeRawSql(net.ibizsys.paas.core.IDEDBCallContext, java.lang.String, net.ibizsys.paas.db.SqlParamList)
	 */
	@Override
	public DBCallResult executeRawSql( IDEDBCallContext iDEDBCallContext, String strSql,SqlParamList sqlParamList) throws Exception
	{
		Session session = this.getCurrentSession();
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("SQL\r\n%1$s", strSql);
			int nIndex =0;
			if(sqlParamList!=null)
			{
				for(SqlParam sqlParam:  sqlParamList)
				{
					sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
					nIndex++;
				}
			}
			log.debug(sb.toString());
		}
		
		final String strSql2 =strSql;
		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();
		final SqlParamList sqlParamList2 = sqlParamList;
		final IDEDBCallContext iDEDBCallContext2 = iDEDBCallContext;
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult = null;
				try
				{
					dbCallResult = getRealDBDialect().callSql(connection, strSql2, sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}
	
	/* (non-Javadoc)
	 * @see net.ibizsys.paas.dao.IDAO#executeRawSql(net.ibizsys.paas.core.IDEDBCallContext, java.lang.String, net.ibizsys.paas.db.SqlParamList)
	 */
	@Override
	public DBCallResult callProc( IDEDBCallContext iDEDBCallContext, String strProcName,SqlParamList sqlParamList) throws Exception
	{
		Session session = this.getCurrentSession();
		
		if(log.isDebugEnabled())
		{
			StringBuilderEx sb = new StringBuilderEx();
			sb.append("存储过程\r\n%1$s", strProcName);
			int nIndex =0;
			if(sqlParamList!=null)
			{
				for(SqlParam sqlParam:  sqlParamList)
				{
					sb.append("\r\n[%1$s] %2$s ==> (%3$s) ", nIndex,sqlParam.getParamName(),sqlParam.getValue());
					nIndex++;
				}
			}
			log.debug(sb.toString());
		}
		
		final String strProcName2 =strProcName;
		final DBCallResultProxy dbCallResultProxy = new DBCallResultProxy();
		final SqlParamList sqlParamList2 = sqlParamList;
		final IDEDBCallContext iDEDBCallContext2 = iDEDBCallContext;
		session.doWork(new Work()
		{
			@Override
			public void execute(Connection connection) throws SQLException
			{
				DBCallResult dbCallResult = null;
				try
				{
					dbCallResult = getRealDBDialect().callProc(connection, strProcName2, sqlParamList2, -1);
					if (dbCallResult.isOk())
					{
						dbCallResultProxy.setDBCallResult(dbCallResult);
					}
					else
					{
						throw new Exception(dbCallResult.getErrorInfo());
					}
				}
				catch (Exception e)
				{
					if (dbCallResult!=null && dbCallResult.getDataSet() != null)
					{
						dbCallResult.getDataSet().close();
					}
					throw new SQLException(StringHelper.format("数据库操作发生异常，%1$s", e.getMessage()),e);
				}
			}
		});

		return dbCallResultProxy.getDBCallResult();
	}
	
	
	/**
	 * 填充继承实体的信息
	 * @param et
	 * @param inheritET
	 * @throws Exception
	 */
	protected void fillInheritEntity(ET et)throws Exception
	{
		
	}
	
	
	@Override
	public void setDBDialect(IDBDialect iDBDialect)
	{
		this.iDBDialect = iDBDialect;
	}
	
	/**
	 * 获取数据库适配器
	 * 
	 * @return
	 */
	public IDBDialect getRealDBDialect()
	{
		if(this.iDBDialect !=null)
			return this.iDBDialect ;
       return this.getDEModel().getSystemRuntime().getDBDialect(this.getDEModel().getDSLink());
    }
	
	 /**
	  * 获取会话工厂
	 * @return
	 */
	public SessionFactory getRealSessionFactory()
	 {
		if(this.sessionFactory!=null)
		{
			return this.sessionFactory;
		}
		
		return this.getDEModel().getSystemRuntime().getSessionFactory(this.getDEModel().getDSLink());
	}
	 
	

	/**
	 * 设置会话工厂
	 * @param sessionFactory
	 */
	public void setSessionFactory(SessionFactory sessionFactory)
	{
		this.sessionFactory = sessionFactory;
	}
	
	
	/**
	 * 获取会话工厂
	 * @return
	 */
	public SessionFactory getSessionFactory()
	{
		return this.sessionFactory;
	}
	 
	 /**
	 * 获取当前会话
	 * @return
	 */
	 @Override
  	 public Session getCurrentSession()throws Exception
     {
    	 return SessionFactoryManager.getCurrentSession(this.getRealSessionFactory());
      }
	   

     
 	/**
 	 * 获取分组语句
 	 * @param strSQL
 	 * @param iDEDataSet
 	 * @return
 	 * @throws Exception
 	 */
 	protected String getGroupSQL(String strSQL, IDEDataSet iDEDataSet) throws Exception
 	{
 		if (StringHelper.isNullOrEmpty(strSQL))
 		{
 			throw new Exception(StringHelper.format("主查询语句无效"));
 		}

 		StringBuilderEx sqlGroup = new StringBuilderEx();

 		IDataEntity majorDataEntity = iDEDataSet.getDataEntity();

 		sqlGroup.append("SELECT ");

 		boolean bFirst = true;

 		int nAliasIndex = 0;

 		//TreeMap<Integer, String> orderMap = new TreeMap<Integer, String>();
 		ArrayList<String> groupFields = new ArrayList<String>();
 		ArrayList<String> orderList = new ArrayList<String>();

 		ArrayList<IDEDataSetGroupParam> recalcItems = new ArrayList<IDEDataSetGroupParam>();
 		
 		java.util.Iterator<IDEDataSetGroupParam> deDataSetGroupParams = iDEDataSet.getDEDataSetGroupParams();
 		
 		while(deDataSetGroupParams.hasNext())
 		{
 			IDEDataSetGroupParam iDEDataSetGroupParam = deDataSetGroupParams.next();
 			if(iDEDataSetGroupParam.isReCalc())
 			{
 				recalcItems.add(iDEDataSetGroupParam);
 				continue;
 			}
 			
 			nAliasIndex++;

 			String strFormular = iDEDataSetGroupParam.getGroupCode();
 			String[] fields = iDEDataSetGroupParam.getGroupFields();

 			if (StringHelper.isNullOrEmpty(strFormular) && fields==null)
 			{
 				continue;
 			}
 			String strFieldCode = "";
 			//String strAlias = iDEDataSetGroupParam.getAlias();
 			String strAlias = iDEDataSetGroupParam.getName();
 			if (fields!=null)
 			{
// 				String[] fields = strDEFields.split("[,]");

 				String[] fieldCodes = new String[fields.length];

 				if (StringHelper.isNullOrEmpty(strFormular))
 				{
 					strFormular = "%1$s";
 					// 取第一个字段
 					String strDEField = fields[0];
 					IDEField defHelper = majorDataEntity.getDEField(strDEField,true);
 					if (defHelper == null)
 					{
 						if (StringHelper.isNullOrEmpty(strAlias))
 							strAlias = fields[0];
 						fieldCodes[0] = strDEField;
 					}
 					else
 					{
 						if (StringHelper.isNullOrEmpty(strAlias))
 							strAlias = fields[0];

 						String strRealCode = getDEFieldStatisticsNullConvertCode(defHelper);
 						fieldCodes[0] = strRealCode;
 					}
 				}
 				else
 				{

 					for (int i = 0; i < fields.length; i++)
 					{
 						String strDEField = fields[i];
 						IDEField defHelper = majorDataEntity.getDEField(strDEField,true);
 						if (defHelper == null)
 						{
 							fieldCodes[i] = strDEField;
 						}
 						else
 						{
 							String strRealCode = getDEFieldStatisticsNullConvertCode(defHelper);
 							fieldCodes[i] = strRealCode;
 						}
 					}
 				}

 				strFieldCode = StringHelper.format(strFormular, fieldCodes);
 			}
 			else
 			{
 				strFieldCode = strFormular;
 			}

 			if (bFirst)
 			{
 				bFirst = false;
 			}
 			else
 				sqlGroup.append(",");

// 			if (StringHelper.isNullOrEmpty(strAlias))
// 			{
// 				strAlias = StringHelper.format("A%1$s", nAliasIndex);
// 				iDEDataSetGroupParam.setAlias(strAlias);
// 			}

 			sqlGroup.append("%1$s as %2$s", strFieldCode, strAlias);

 			if (iDEDataSetGroupParam.isEnableGroup())
 				groupFields.add(strFieldCode);

 			if (!StringHelper.isNullOrEmpty(iDEDataSetGroupParam.getSortDir()))
 			{
 				orderList.add(StringHelper.format("%1$s %2$s", strAlias, iDEDataSetGroupParam.getSortDir()));
 				//orderMap.put(iDEDataSetGroupParam.getOrder(), StringHelper.format("%1$s %2$s", strAlias, iDEDataSetGroupParam.getSortDir()));
 			}

 			// 增加变量
// 			String strParams = iDEDataSetGroupParam.getUserTag();
// 			if (!StringHelper.isNullOrEmpty(strParams))
// 			{
// 				String[] params = strParams.split("[;]");
// 				for (int i = 0; i < params.length; i++)
// 				{
// 					CallParam cp = new CallParam();
// 					cp.setParamName(params[i]);
// 					CallResult callResult = MacroHelper.GetValue(cp.getParamName(), webContext, globalHelperEx, strCurPersonId, baseDataEntity);
// 					if (callResult.getRetCode() == Errors.OK)
// 					{
// 						Object objValue = callResult.getUserObject();
// 						if (objValue == null || StringHelper.Compare(objValue.toString(), cp.getParamName(), true) != 0)
// 						{
// 							cp.setValue(objValue);
// 						}
// 					}
// 					list.add(cp);
// 				}
// 			}

 		}
 		sqlGroup.append(" FROM (%1$s) m1 ", strSQL);

 		if (groupFields.size() == 0)
 		{
 			throw new Exception(StringHelper.format("没有指定任何分组属性"));
 		}

 		bFirst = true;
 		// 执行分组
 		for (String strFieldCode : groupFields)
 		{
 			if (bFirst)
 			{
 				sqlGroup.append(" GROUP BY ");
 				bFirst = false;
 			}
 			else
 			{
 				sqlGroup.append(" , ");
 			}
 			sqlGroup.append(strFieldCode);
 		}

 		String strGroupSql = sqlGroup.toString();
 		if(recalcItems.size()>0)
 		{
 			sqlGroup.reset();
 			sqlGroup.append("SELECT m3.*");
 			for(IDEDataSetGroupParam iDEDataSetGroupParam:recalcItems)
 			{
 				nAliasIndex++;

 				String strFormular = iDEDataSetGroupParam.getGroupCode();
 				String[] fields = iDEDataSetGroupParam.getGroupFields();

 				if (StringHelper.isNullOrEmpty(strFormular) && fields == null)
 				{
 					continue;
 				}
 				String strFieldCode = "";
 				String strAlias = iDEDataSetGroupParam.getName();

 				strFieldCode = strFormular;
 				sqlGroup.append(",");

// 				if (StringHelper.isNullOrEmpty(strAlias))
// 				{
// 					strAlias = StringHelper.format("A%1$s", nAliasIndex);
// 					iDEDataSetGroupParam.setAlias(strAlias);
// 				}

 				sqlGroup.append("%1$s as %2$s", strFieldCode, strAlias);
 				
 				if (!StringHelper.isNullOrEmpty(iDEDataSetGroupParam.getSortDir()))
 				{
 					orderList.add(StringHelper.format("%1$s %2$s", strAlias, iDEDataSetGroupParam.getSortDir()));
// 					orderMap.put(iDEDataSetGroupParam.getOrder(), StringHelper.format("%1$s %2$s", strAlias, iDEDataSetGroupParam.getSortDir()));
 				}
 			}
 			
 			sqlGroup.append(" FROM (%1$s) m3",strGroupSql);
 			strGroupSql = sqlGroup.toString();
 		}
 		
// 		if(!StringHelper.isNullOrEmpty(queryGroupModelConfig.getGroupCond()))
// 		{
// 			sqlGroup.reset();
// 			sqlGroup.append("SELECT m4.*");
// 			sqlGroup.append(" FROM (%1$s) m4 where %2$s",strGroupSql,queryGroupModelConfig.getGroupCond());
// 			strGroupSql = sqlGroup.toString();
// 		}
 		
 		if (orderList.size() > 0)
 		{
 			StringBuilderEx sqlGroupEx = new StringBuilderEx();
 			sqlGroupEx.append("SELECT * FROM (%1$s) m2 ", strGroupSql);

 			bFirst = true;
 			for(String strOrderCode:orderList)
 			//for (int nValue : orderMap.keySet())
 			{
 				if (bFirst)
 				{
 					sqlGroupEx.append(" ORDER BY ");
 					bFirst = false;
 				}
 				else
 					sqlGroupEx.append(" , ");

 				sqlGroupEx.append(strOrderCode);
 			}
 			strGroupSql = sqlGroupEx.toString();
 		}

 		if (iDEDataSet.getGroupTopCount() <= 0)
 			return strGroupSql;

 		return this.getRealDBDialect().getTopRowSQL(strGroupSql, iDEDataSet.getGroupTopCount());
 	}
 	

 	/**
 	 * 获取属性统计空值时转换代码
 	 * @param defHelper
 	 * @return
 	 */
 	protected String getDEFieldStatisticsNullConvertCode(IDEField defHelper)
 	{
// 		String strStaNullConv = defHelper.GetDTColumn().GetStatisticsNullConvert();
// 		if (!StringHelper.IsNullOrEmpty(strStaNullConv))
// 		{
// 			return StringHelper.Format("(CASE WHEN %1$s IS NULL THEN %2$s ELSE %1$s END)", defHelper.GetDTColumn().GetFormalColumnName(), strStaNullConv);
// 		}
// 		else
// 			return defHelper.getName();
 		return defHelper.getName();
 	}	

 	
 	/* (non-Javadoc)
	 * @see net.ibizsys.paas.dao.IDAO#getDSLink()
	 */
	@Override
	public String getDSLink()
	{
		return strDSLink;
	}


	/* (non-Javadoc)
	 * @see net.ibizsys.paas.dao.IDAO#setDSLink(java.lang.String)
	 */
	@Override
	public void setDSLink(String strDSLink)
	{
		this.strDSLink = strDSLink;
	}


	@Override
	public void postConstruct()throws Exception {
		
	}
	
	
	
}
